package com.huayu.languo.common.util;

import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class ThreadPoolManager {

    private static final int DOB_ONECPU = 10;

    private static final int KEEP_ALIVE_TIME = 60;

    private static final Logger LOG = LoggerFactory.getLogger(ThreadPoolManager.class);

    private static volatile ThreadPoolManager threadPoolManager;

    private ThreadPoolExecutor threadPool;

    /**
     * 消息缓冲队列大小
     */
    private int queueSize = Integer.parseInt(AppProperties.getSysEnvOrProp("gm.thread.pool.thread.queueSize", "2000"));

    private ThreadPoolManager() {
        Integer configuredThreadCount = Integer.parseInt(AppProperties.getSysEnvOrProp("gm.thread.pool.thread.count", "100"));

        //并发处理的线程数量
        if (configuredThreadCount == null) {
            configuredThreadCount = Runtime.getRuntime().availableProcessors() * DOB_ONECPU;
        }
        this.threadPool = new ThreadPoolExecutor(configuredThreadCount, configuredThreadCount, KEEP_ALIVE_TIME, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<Runnable>(queueSize),
                        new NamedThreadFactory("bbt-worker"), new AbortPolicy());

    }

    public static ThreadPoolManager getInstance() {
        if (threadPoolManager == null) {
            synchronized (ThreadPoolManager.class) {
                if (threadPoolManager == null) {
                    threadPoolManager = new ThreadPoolManager();
                }
            }
        }
        return threadPoolManager;
    }

    public <T extends AbstractTask> void executeTask(T task, final Map<String, Object> context) {
        try {
            task.setContext(context);
            threadPool.submit(task);
        } catch (RejectedExecutionException ree) {
            LOG.warn("All  worker threads are currently busy, waiting 50 ms, task name = [{}],emsg=[{}] ", new Object[] {task.getClass().getName(), ree.getMessage(), ree});
        }
    }
}
